// @File:           RedisTool.cpp
// @ProjectName:    mosquitto_auth_plugin
// @Description:    ${description}
// @Author:         wujehy
// @Email:          wujehy@qq.com
// @Time:           2021-03-16 14:47

#include "RedisTool.h"
#include "hiredis.h"
#include "Logger.h"
int RedisTool::init() {
    if (context == nullptr)
    {
        // 初始化
        context = redisConnect(host.c_str() , port);
        if (context == NULL || context->err) {
            if (context) {
                printf("Connection error: %s\n", context->errstr);
                redisFree(context);
            } else {
                printf("Connection error: can't allocate redis context\n");
            }
            return -1;
        }

        redisReply* reply = static_cast<redisReply *>(redisCommand(context, "PING"));
        std::string respData(reply->str , reply->len);
        freeReplyObject(reply);
        if (respData == "PONG") {
            // 成功
            gDebug<<"链接redis 成功";
            return 0;
        }
        gWarning<<"ping 失败 , 正在尝试 密码登录";
        // 失败 使用密码
        if (password.length() == 0 )
        {
            // 为设置 密码
            gError<<"密码为空";
            return -1;
        }

        redisReply* replypassword = (redisReply *)redisCommand(context, "AUTH %s", "123456");
        std::string respDatapassword(replypassword->str , replypassword->len);
        freeReplyObject(replypassword);

        if (respDatapassword == REDIS_TOOL_OK)
        {
            gDebug<<"使用密码链接redis 成功";
            return 0;
        }

        gError<<"链接redis失败";
        return -1;
//        printf("PING: %s\n", reply->str);
    } else{
        // 已经初始化了

        gDebug<<"redis 已经初始化啦";
    }
    return 0;
}

void RedisTool::setDb(const std::string &db) {
    RedisTool::db = db;
}


void RedisTool::setPassword(const std::string &password) {
    RedisTool::password = password;
}

RedisTool::~RedisTool() {
    if (context != nullptr)
    {
        redisFree(context);
    }
}

void RedisTool::setHost(const std::string &host) {
    RedisTool::host = host;
}

void RedisTool::setPort(int port) {
    RedisTool::port = port;
}

RedisTool::RedisTool() {
}

int RedisTool::setKey(const std::string &key, const std::string &value , int expire ) {

    redisReply *reply ;
    if (expire <= 0 )
    {
        reply = static_cast<redisReply *>(redisCommand(context, "set %b %b", key.c_str(), (size_t) key.length(), value.c_str(), (size_t) value.length()));
    }else
    {
        reply = static_cast<redisReply *>(redisCommand(context, "SETEX %b %d %b", key.c_str(), (size_t) key.length(),expire , value.c_str(), (size_t) value.length()));

    }
    std::string respData(reply->str , reply->len);
    freeReplyObject(reply);
    if (respData == REDIS_TOOL_OK)
    {
        return 0;
    }
    return -1;
}

int RedisTool::getKey(const std::string &key, std::string &value) {
    redisReply *reply = static_cast<redisReply *>(redisCommand(context, "get %b", key.c_str(), (size_t) key.length()));
    value = std::string(reply->str , reply->len);
    freeReplyObject(reply);
    if (value.length() == 0 )
    {
        // 失败
        return -1;
    }
    return 0;
}
